package com.gitee.wsl.io.channel.read

import com.gitee.wsl.annotation.InternalAPI
import kotlinx.io.Buffer


fun ByteReadChannel.counted(): CountedByteReadChannel = CountedByteReadChannel(this)

 class CountedByteReadChannel( val delegate: ByteReadChannel) : ByteReadChannel {
    private val buffer = Buffer()
    private var initial = 0L
    private var consumed = 0L

     val totalBytesRead: Long
        get() {
            updateConsumed()
            return consumed
        }

    override val closedCause: Throwable?
        get() = delegate.closedCause

    override val isClosedForRead: Boolean
        get() = buffer.exhausted() && delegate.isClosedForRead

    @InternalAPI
    override val readBuffer: Buffer
        get() {
            updateConsumed()
            val appended = buffer.transferFrom(delegate.readBuffer)
            initial += appended
            return buffer
        }

    @OptIn(InternalAPI::class)
    override suspend fun awaitContent(min: Int): Boolean {
        return readBuffer.size >= min || delegate.awaitContent(min)
    }

    override fun cancel(cause: Throwable?) {
        delegate.cancel(cause)
        buffer.close()
    }

    private fun updateConsumed() {
        consumed += initial - buffer.size
        initial = buffer.size
    }
}